package em.util;

import base.cache.CacheManager;
import base.util.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.StrKit;
import org.apache.log4j.Logger;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;

import java.io.*;
import java.util.*;

/**  
 * 取、设实体对象的各属性值   
 *  
 */   
public class CommonTools {

	private static CommonTools commonTools=new CommonTools() ;
	Logger log=Logger.getLogger(CommonTools.class);

	public static CommonTools getInstance(){
		return commonTools;
	}

	public int num2bit(int num, int index){
        return (num & (0x1 << index)) >> index;
    }
    
    /**
	 * 通过sqlKey查询sql语句，并查询出结果，返回List<Record>
	 * strSqlKey格式 如：emp.empList  emp为文件名;empList为emp文件里的一个sql语句的Key值
	 */
	public String getSql(String strSqlKey,Map<String,Object> map){
		String strSql="";
		if(StrKit.isBlank(strSqlKey)){ log.error("取得sql语句的关键字为空");return strSql;}
		if(strSqlKey.indexOf(".")==-1){ log.error("sql语句的关键字不正确："+strSqlKey);return strSql;}

		//取得sql
		Map<String,String> mapSql=CacheManager.getInstance().get(ConstUtil.CACHE_KEY_GLOBAL_SQL);
		strSql =  mapSql.get(strSqlKey);
		if(StrKit.isBlank(strSql)) return strSql;

		//没有参数就直接返回sql语句
		if(map==null) return strSql;

		//使用velocity模板，实例化velocity上下文
		VelocityContext context = new VelocityContext();
		for(Map.Entry<String,Object> entry:map.entrySet()){
			context.put(entry.getKey(), entry.getValue());
		}
		
		StringWriter result = new StringWriter();
		try {
			Velocity.evaluate(context, result, "report" + strSqlKey, strSql);
		} catch (ParseErrorException | MethodInvocationException
				| ResourceNotFoundException e) {
			return "";
		}
		return result.toString();
	}
	
	public String getSql(String strSqlKey,HashMap<String,Object> map){
		return getSql(strSqlKey,(Map)map);
	}

	public String getSql(String strSqlKey){
		return getSql(strSqlKey,null);
	}

	/**
	 * 随机生成字符串(16位数)
	 * @return
	 */
	public String getRandom(int iLength){
		String base = ConstUtil.C_RANDOM;
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < iLength; i++) {
			sb.append(base.charAt(random.nextInt(62)));
		}
		return sb.toString();
	}

	/**
	 * 生成树形结构数据
	 * @param jsonArray 原数据
	 * @param strPIDValue 具体值   如菜单里,顶级菜单的值 ""
	 * @param strId Id字段			如菜单里的"MenuId"
	 * @param strPid 继承Id的字段	如菜单里的"Pid"
	 * @return
     */
	public JSONArray findSub(JSONArray jsonArray,String strPIDValue,String strPid,String strId){
		JSONArray jsonArray1=new JSONArray();
		for (Object object:jsonArray){
			JSONObject jsonObject=(JSONObject)object;
			if(strPIDValue.equals(jsonObject.getString(strPid))){
				JSONArray c_node = findSub(jsonArray, jsonObject.getString(strId),strPid,strId);
				if(c_node.size()>0)
					jsonObject.put("sub", c_node);
				jsonArray1.add(jsonObject);
			}
		}
		return jsonArray1;
	}

	/**
	 * 16进制转成2进制
	 * @param strHex
	 * @return
     */
	public String hexTo2Scale(String strHex){
		strHex = strHex.toUpperCase();
		String result = "";
		for (int i = 0; i < strHex.length(); i++) {
			char c = strHex.charAt(i);
			if (c == '0') {
				result += "0,0,0,0";
			} else if (c == '1') {
				result += "0,0,0,1";
			} else if (c == '2') {
				result += "0,0,1,0";
			} else if (c == '3') {
				result += "0,0,1,1";
			} else if (c == '4') {
				result += "0,1,0,0";
			} else if (c == '5') {
				result += "0,1,0,1";
			} else if (c == '6') {
				result += "0,1,1,0";
			} else if (c == '7') {
				result += "0,1,1,1";
			} else if (c == '8') {
				result += "1,0,0,0";
			} else if (c == '9') {
				result += "1,0,0,1";
			} else if (c == 'A') {
				result += "1,0,1,0";
			} else if (c == 'B') {
				result += "1,0,1,1";
			} else if (c == 'C') {
				result += "1,1,0,0";
			} else if (c == 'D') {
				result += "1,1,0,1";
			} else if (c == 'E') {
				result += "1,1,1,0";
			} else if (c == 'F') {
				result += "1,1,1,1";
			}
			result+=",";
		}
		return StrKit.notBlank(result)?result.substring(0,result.length()-1):"";
	}

	/**
	 * 16进制转成10进制
	 * @param strHex
	 * @return
     */
	public String hexTo10Scale(String strHex){
		return Long.valueOf(strHex,16).toString();
	}

	/**
	 * 将流数据转换成字符串
	 *
     */
	public String convertInputStreamToString(InputStream input){
		StringBuffer out = new StringBuffer();
		byte[] b = new byte[1024 * 4];
		try {
			for (int n; (n = input.read(b)) != -1;) {
                out.append(new String(b, 0, n,ConstUtil.ENCODING_UTF_8));
            }
		} catch (IOException e) {
			log.error("转换数据类型失败:"+e.getMessage());
			e.printStackTrace();
		}
		return out.toString();
	}

	public boolean notBlank(Object str) {
		return str != null && !"".equals(str.toString().trim());
	}

	public boolean isBlank(Object str) {
		return str == null || "".equals(str.toString().trim());
	}

	/**
	 * 两个数据进行比较
	 * @param obj1
	 * @param obj2
     * @return
     */
	public boolean compare(Object obj1,Object obj2){
		String str1=isBlank(obj1)?"":obj1.toString();
		String str2=isBlank(obj2)?"":obj2.toString();
		if(str1.equals(str2))
			return true;
		return false;
	}

	/**
	 * 将字符串转换成int
	 * @param strValue
	 * @return
     */
	public int convertStrToInt(String strValue){
		try{
			return Integer.parseInt(strValue);
		}catch (Exception ex){
			ex.printStackTrace();
			log.error("数据转换失败:"+ex.getMessage());
			throw ex;
		}
	}

	/**
	 * 复制对象
	 * @param src
	 * @param <T>
     * @return
     */
	public <T>T copyObject(T src){
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(bos);
			oos.writeObject(src);
			
			ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
			ObjectInputStream ois = new ObjectInputStream(bis);
			return (T) ois.readObject();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 取得百分比
	 * @param d
	 * @return
     */
	public String getPercent(double d){
		java.text.DecimalFormat   df=new   java.text.DecimalFormat("#.##");
		return df.format(d*100)+"%";
	}

	/**
	 * 取得两位小数点
	 * @param d
	 * @return
     */
	public String getTwoPoint(double d){
		java.text.DecimalFormat   df=new   java.text.DecimalFormat("#.##");
		return df.format(d);
	}

	/**
	 * 月的类型来取得初始时间
	 * 0:本月
	 * 1:三个月
	 * 2:半年
	 * 3:本年度
	 * @param monthType
	 * @return
	 */
	public String getStartTime(String monthType){
		String strStartTime="";
		Date date=null;
		//时间
		if("0".equals(monthType)){
			date= DateUtil.getInstance().getFirstDayOfMonth(DateUtil.getInstance().getCurrentDate());
			strStartTime=DateUtil.getInstance().getString(date,DateUtil.getInstance().formatLong);
		}else if("1".equals(monthType)) {//三个月
			date=DateUtil.getInstance().addMonth(DateUtil.getInstance().getCurrentDate(),-2);
			if(DateUtil.getInstance().getCurrentDate().getMonth()<3){ strStartTime=DateUtil.getInstance().getString(DateUtil.getInstance().getCurrentDate(),"Y")+"-01-01 0:00:00";}
			else{
				date=DateUtil.getInstance().getFirstDayOfMonth(date);
				strStartTime=DateUtil.getInstance().getString(date,DateUtil.getInstance().formatLong);
			}
		}else if("2".equals(monthType)) {//半年
			date=DateUtil.getInstance().addMonth(DateUtil.getInstance().getCurrentDate(),-5);
			if(DateUtil.getInstance().getCurrentDate().getMonth()<6){ strStartTime=DateUtil.getInstance().getString(DateUtil.getInstance().getCurrentDate(),"Y")+"-01-01 0:00:00";}
			else{
				date=DateUtil.getInstance().getFirstDayOfMonth(date);
				strStartTime=DateUtil.getInstance().getString(date,DateUtil.getInstance().formatLong);
			}
		}else{//本年度
			strStartTime=DateUtil.getInstance().getString(DateUtil.getInstance().getCurrentDate(),"Y")+"-01-01 0:00:00";
		}

		return strStartTime;
	}
}
